#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTableWidgetItem>
#include <QMenu>
#include <QAction>
#include <QPoint>
#include <QThread>
#include <QNetworkInterface>
#include <QMutex>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

// 前向声明
class IPScanWorker;
class NetTestWorker;
class LogMonitorWorker;
class ListTestWorker;

/**
 * @brief IP地址扫描工作线程类
 * 
 * 用于在后台线程中获取本机所有IP地址
 */
class IPScanWorker : public QObject
{
    Q_OBJECT
    
public:
    explicit IPScanWorker(QObject *parent = nullptr);
    
public slots:
    /**
     * @brief 执行IP地址扫描
     */
    void scanIPAddresses();
    
signals:
    /**
     * @brief IP地址列表扫描完成信号
     * @param ipList 扫描到的IP地址列表
     */
    void ipScanFinished(const QStringList &ipList);
    
    /**
     * @brief 工作完成信号
     */
    void finished();
};

/**
 * @brief 日志监控工作线程类
 * 
 * 用于监控网络测试过程中日志的变化，实时更新到UI
 */
class LogMonitorWorker : public QObject
{
    Q_OBJECT
    
public:
    explicit LogMonitorWorker(QObject* parent = nullptr);
    
    /**
     * @brief 设置要监控的日志引用
     * @param logRef 日志字符串的引用
     */
    void setLogReference(const std::string& logRef);
    
public slots:
    /**
     * @brief 开始监控日志变化
     */
    void startMonitoring();
    
signals:
    /**
     * @brief 日志更新信号
     * @param newLog 新增的日志内容
     */
    void logUpdated(const QString& newLog);
    
    /**
     * @brief 监控完成信号
     */
    void finished();
    
private:
    std::string m_lastContent;  // 上次检查时的日志内容
    const std::string* m_logRef;  // 指向要监控的日志的指针
    QMutex m_mutex;  // 用于线程安全
};

/**
 * @brief 网络测试工作线程类
 * 
 * 在后台线程中执行网络测试操作
 */
class NetTestWorker : public QObject
{
    Q_OBJECT
    
public:
    explicit NetTestWorker(QObject* parent = nullptr);
    
    /**
     * @brief 设置测试参数
     * @param type 测试类型（ping/telnet/tracert）
     * @param localIp 本地IP地址
     * @param targetIp 目标IP地址
     * @param port 目标端口
     */
    void setParams(const QString& type, const QString& localIp, const QString& targetIp, const QString& port);
    
public slots:
    /**
     * @brief 执行网络测试
     */
    void doTest();
    
signals:
    /**
     * @brief 日志更新信号
     * @param log 更新的日志内容
     */
    void logUpdated(const QString& log);
    
    /**
     * @brief 测试完成信号
     * @param result 测试结果
     */
    void testFinished(const QString& result);
    
private:
    QString m_type;
    QString m_localIp;
    QString m_targetIp;
    QString m_port;
};

/**
 * @brief 主窗口类
 * 
 * 实现网络测试工具的主要功能，包括：
 * 1. 显示网络连接列表
 * 2. 添加新的网络连接
 * 3. 修改现有连接信息
 * 4. 删除选中的连接
 * 5. 表格右键菜单功能
 * 6. 日志记录功能
 * 7. 网络测试功能
 */
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    /**
     * @brief 构造函数
     * @param parent 父窗口指针
     */
    explicit MainWindow(QWidget *parent = nullptr);
    
    /**
     * @brief 析构函数
     */
    ~MainWindow();
    static MainWindow* getInstance() { return instance; }
    Ui::MainWindow* getUi() { return ui; }

    // 添加线程安全的UI操作方法
    QString getTestParameters(int row, int column);
    QString getCurrentIp();
    void updateTableStatus(int row, const QString& status);
    bool isRowChecked(int row);

signals:
    // 添加需要更新状态的信号
    void needUpdateStatus(int row, const QString& status);

private slots:
    /**
     * @brief 添加按钮点击处理函数
     * 添加新的网络连接到表格中
     */
    void onAddButtonClick();
    
    /**
     * @brief 修改按钮点击处理函数
     * 修改选中的网络连接信息
     */
    void onModifyButtonClick();
    
    /**
     * @brief 删除按钮点击处理函数
     * 删除选中的网络连接
     */
    void onDeleteButtonClick();
    
    /**
     * @brief 表格选择变更处理函数
     * 处理表格选择变化，更新按钮状态和输入框内容
     */
    void onSelectionChanged();
    
    /**
     * @brief 执行按钮点击处理函数
     */
    void onExecuteButtonClick();
    
    /**
     * @brief 停止按钮点击处理函数
     */
    void onStopButtonClick();
    
    /**
     * @brief 测试按钮点击处理函数
     * 开始网络测试
     */
    void onTestButtonClick();
    
    /**
     * @brief 显示表格上下文菜单
     * @param pos 鼠标右键点击位置
     */
    void showTableContextMenu(const QPoint& pos);
    
    /**
     * @brief 全选表格中的行
     */
    void onSelectAll();
    
    /**
     * @brief 反选表格中的行
     */
    void onInvertSelection();
    
    /**
     * @brief 全不选表格中的行
     */
    void onDeselectAll();
    
    /**
     * @brief 上移选中的行
     */
    void onMoveUp();
    
    /**
     * @brief 下移选中的行
     */
    void onMoveDown();
    
    /**
     * @brief 处理IP扫描完成
     * @param ipList 扫描到的IP地址列表
     */
    void onIPScanFinished(const QStringList &ipList);
    
    /**
     * @brief 处理网络测试日志更新
     * @param log 更新的日志内容
     */
    void onTestLogUpdated(const QString &log);
    
    /**
     * @brief 处理网络测试完成
     * @param result 测试结果
     */
    void onTestFinished(const QString &result);
    
    /**
     * @brief 查看选中行的测试日志
     */
    void onViewLog();
    

private:
    static MainWindow* instance;
    Ui::MainWindow *ui;  // UI界面指针
    
    // 右键菜单相关
    QMenu* tableContextMenu;         // 表格右键菜单
    QAction* selectAllAction;        // 全选动作
    QAction* invertSelectionAction;  // 反选动作
    QAction* deselectAllAction;      // 全不选动作
    QAction* moveUpAction;           // 上移动作
    QAction* moveDownAction;         // 下移动作
    
    // IP扫描相关
    QThread* ipScanThread = nullptr;           // IP扫描线程
    IPScanWorker* ipScanWorker = nullptr;      // IP扫描工作对象
    
    // 网络测试相关
    QThread* netTestThread = nullptr;          // 网络测试线程
    NetTestWorker* netTestWorker = nullptr;    // 网络测试工作对象
    
    // 日志监控相关
    QThread* logMonitorThread = nullptr;       // 日志监控线程
    LogMonitorWorker* logMonitorWorker = nullptr; // 日志监控工作对象
    
    // ListTestWorker相关
    QThread* listTestThread = nullptr;          // ListTest线程
    ListTestWorker* listTestWorker = nullptr;    // ListTest工作对象
    
    /**
     * @brief 检查当前程序是否有管理员权限
     * @return 如果有管理员权限返回true，否则返回false
     */
    bool checkPermissions();

    /**
     * @brief 初始化表格
     * 设置表格列宽并添加测试数据
     */
    void initTable();
    
    /**
     * @brief 清空输入框
     * 清空所有输入框的内容
     */
    void clearInputFields();
    
    /**
     * @brief 更新选中行数据到输入框
     * 将表格中选中行的数据填充到输入框中
     */
    void updateSelectedRowData();
    
    /**
     * @brief 创建表格右键菜单
     */
    void createContextMenu();
    
    /**
     * @brief 添加日志到主日志窗口
     * @param log 日志内容
     */
    void appendMainLog(const QString& log);
    
    /**
     * @brief 添加日志到线程日志窗口
     * @param log 日志内容
     */
    void appendThreadLog(const QString& log);
    
    /**
     * @brief 初始化IP扫描线程
     */
    void initIPScanThread();
    
    /**
     * @brief 初始化网络测试线程
     * @param testType 测试类型
     * @param localIp 本地IP地址
     * @param targetIp 目标IP地址
     * @param port 目标端口
     */
    void initNetTestThread(const QString& testType, const QString& localIp, 
                          const QString& targetIp, const QString& port);
    
    // JSON数据处理函数
    void saveTableToJson();
    void loadTableFromJson();
};

// ========== ListTestWorker 类 ==========
class ListTestWorker : public QObject
{
    Q_OBJECT
    
public:
    explicit ListTestWorker(QObject *parent = nullptr);
    
    /**
     * @brief 设置行索引
     * @param index 要测试的表格行索引
     */
    void setRowIndex(int index);
    
public slots:
    /**
     * @brief 执行测试
     */
    void doTest();
    
signals:
    /**
     * @brief 测试完成信号
     */
    void testFinished();
    
    /**
     * @brief 更新状态信号
     * @param row 行索引
     * @param status 状态文本
     */
    void updateStatus(int row, const QString& status);
    
private:
    int m_rowIndex; // 当前测试的行索引
    Ui::MainWindow* ui;
};

#endif // MAINWINDOW_H
